// ChessXMLGenerator.h
//
// Created By: Jeremy Butler
// Created On: 23-Mar-2011

#include "ChessXMLGenerator.h"
#include "fstream"
#include <boost/lexical_cast.hpp>
using namespace std;

ChessXMLGenerator::ChessXMLGenerator() : outputstring(), game(){
  return;
}

ChessXMLGenerator::ChessXMLGenerator(const Game * _game) : outputstring(), game(_game){
  if(game == NULL)
    throw InvalidArgumentException("Need a game object to produce XML");
  return;
}

ChessXMLGenerator::ChessXMLGenerator(const ChessXMLGenerator & other) :
    outputstring(other.outputstring){
  return;
}

ChessXMLGenerator & ChessXMLGenerator::operator = (const ChessXMLGenerator & other){
  if(this != &other){
    outputstring = other.outputstring;
  }
  return *this;
}

ChessXMLGenerator::~ChessXMLGenerator(){
  return;
}

void ChessXMLGenerator::GenerateChessXML(const string & fileName){
  outputstring += "<chessgame>\n";
  GenerateBoardXML();
  GenerateHistoryXML();
  outputstring += "</chessgame>\n";

  ofstream xmlStream;
  xmlStream.open(fileName.c_str());
  if(xmlStream.is_open()){
    xmlStream << outputstring;
    xmlStream.close();    
  }
  else
    throw IOException("Error Writing to file: " + fileName);

  
  return;
}

void ChessXMLGenerator::GenerateBoardXML(){
  outputstring += "\t<board>\n";
  for(int i = 0; i < 8; i++){
    for(int j = 0; j < 8; j++){
      const Piece * piece = (*game)(i,j);
      GeneratePieceXML(piece,i,j,2);
    }
  }
  outputstring += "\t</board>\n";
}

void ChessXMLGenerator::GenerateHistoryXML(){
  outputstring += "\t<history>\n";
  deque<Move> history(game->GetHistory());

  for(deque<Move>::iterator it = history.begin(); it != history.end(); it++){
    GenerateMoveXML(*it);
  }

  outputstring += "\t</history>\n";
}

void ChessXMLGenerator::GeneratePieceXML(const Piece * piece, int row, int col, int indent){
  if(piece){
    for(int i = 0; i < indent; i++)
      outputstring += "\t";
    outputstring += "<piece type=\"" + Piece::TypetoString(piece->GetType());
    outputstring += "\" color=\"";
    outputstring += ((piece->GetColor() == WHITE) ? "white" : "black");
    outputstring += "\" row=\"" + boost::lexical_cast<string>(row);
    outputstring += "\" column=\"" + boost::lexical_cast<string>(col) + "\" />\n";
  }
}

void ChessXMLGenerator::GenerateMoveXML(const Move & move){
  int row,col;
  outputstring += "\t\t<move>\n";
  row = move.GetFromLocation().GetY();
  col = move.GetFromLocation().GetX();
  GeneratePieceXML(move.GetFromPiece(),row,col,3);
  row = move.GetToLocation().GetY();
  col = move.GetToLocation().GetX();
  GeneratePieceXML(move.GetToPiece(),row,col,3);
  if(move.GetTakenPiece())
    GeneratePieceXML(move.GetTakenPiece(),row,col,3);
  outputstring += "\t\t</move>\n";
}
